import uuid
import logging

from 程序核心代码.mvvm重构.基础定义.节点管理器.动态数据调度器.属性管理器 import 属性管理基类

# 配置日志记录器
logging.basicConfig(level=logging.ERROR, format='%(asctime)s - %(levelname)s - %(message)s')
日志记录器 = logging.getLogger(__name__)

from 程序核心代码.mvvm重构.基础定义.基础图形项.节点接口.节点接口定义 import 节点接口模型
from 程序核心代码.mvvm重构.基础定义.基础模型.通用基础模型 import 节点模型基类


class ast节点基础模型(属性管理基类):
    def __init__(self, ast节点, 所属节点模型管理器, 节点名称: str = None, 节点位置=None, 上级节点=None,**kwargs):
        super().__init__()
        # 节点私有属性 只在模型层使用
        self._ast节点 =  ast节点
        if self._ast节点 is None:
            raise ValueError("ast节点不能为空")
        self.所属节点模型管理器 = 所属节点模型管理器
        if self.所属节点模型管理器 is None:
            raise ValueError("所属节点管理器不能为空")
        self._是控制节点 = False
        self._上层是否为控制节点 = False
        self._下级节点列表 = []
        self.接口字典={"执行流":{"输入":None,"输出":None},"调用流":{"输入":None,"输出":None} ,"数据流":{"输入":[],"输出":None} }
        self.节点名称=节点名称
        self.节点位置=节点位置
        if self.获取属性值("节点名称") is None:
            raise ValueError("节点名称不能为空")
        self._节点位置 = self.获取属性值("节点位置")
        if self._节点位置 is None:
            self._节点位置 = [0, 0]
            self._设置自身属性("节点位置", self._节点位置)
        self.上级节点 = self.获取属性值("上级节点")
        self.节点ast类型 = self._ast节点.__class__
        self._节点ID = str(getattr(self._ast节点, '_节点ID', uuid.uuid4()))

        self.注册属性触发函数("节点介绍", self._节点介绍变动回调)
        self.自动注册到所属节点模型管理器()
        self.无图形项 = False

        # 设置调试模式
        self.调试模式 = False
        if self.调试模式:
            日志记录器.setLevel(logging.DEBUG)
            日志记录器.debug(f"{self.__class__.__name__} 调试模式已开启")
        else:
            日志记录器.setLevel(logging.ERROR)

        日志记录器.info("ast节点基础模型已初始化")

    @property
    def 节点名称(self):
        return self.获取属性值("节点名称")
    @节点名称.setter
    def 节点名称(self, value):
        self.设置属性("节点名称", value)
    @property
    def 参数名(self):
        return self.获取属性值("参数名")
    @参数名.setter
    def 参数名(self, value):
        self.设置属性("参数名", value)
    @property
    def 参数值(self):
        return self.获取属性值("参数值")
    @参数值.setter
    def 参数值(self, value):
        self.设置属性("参数值", value)
    @property
    def 参数值修改回调(self):
        return self.获取属性值("参数值修改回调")
    @参数值修改回调.setter
    def 参数值修改回调(self, value):
        self.设置属性("参数值修改回调", value)
    @property
    def 节点位置(self):
        return self.获取属性值("节点位置")
    @节点位置.setter
    def 节点位置(self, value):
        self.设置属性("节点位置", value)
    @property
    def 节点ID(self):
        return self._节点ID
    @property
    def 节点介绍(self):
        return self.获取属性值("节点介绍")
    @节点介绍.setter
    def 节点介绍(self, value):
        self.设置属性("节点介绍", value)

    @property
    def 节点状态(self):
        if self.获取属性值("节点图形项管理状态") is None:
            return "未检查节点状态"
        return self.获取属性值("节点图形项管理状态")
    @节点状态.setter
    def 节点状态(self, value):
        self.设置属性("节点图形项管理状态", value)
    @property
    def 警告信息(self):
        return self.获取属性值("警告信息")
    @警告信息.setter
    def 警告信息(self, value):
        self.设置属性("警告信息", value)
    @property
    def 异常信息(self):
        return self.获取属性值("异常信息")
    @异常信息.setter
    def 异常信息(self, value):
        self.设置属性("异常信息", value)

    def 自动注册到所属节点模型管理器(self):
        日志记录器.debug("自动注册到所属节点模型管理器")
        if not isinstance(self._ast节点, list):
            self._ast节点._节点ID = self._节点ID
        self.所属节点模型管理器.节点模型列表.append(self)
        self.所属节点模型管理器.节点模型字典[self._节点ID] = self
        self.所属节点模型管理器.节点布局管理器.添加节点(self._节点ID)
        日志记录器.debug(f"节点 {self._节点ID} 已注册到管理器")

    def _节点介绍变动回调(self):
        # 图形项属性 "节点介绍" 模型变动时触发的函数
        self._节点介绍 = self.获取属性值("节点介绍")
        日志记录器.debug(f"节点介绍已更新为: {self._节点介绍}")

    def 添加接口到节点(self, 流类型, 方向, 接口名称=None, 数据类型=None, 必须连接=False, 序号=-1) -> 节点接口模型:
        try:
            接口 = self.查找接口(流类型, 方向)
            if 接口:
                if 流类型=="数据流" :
                    if 方向=="输入":
                        #检查接口是否是列表
                        if isinstance(接口, list):

                            for 数据流接口 in 接口: # 此时应为列表
                                if 数据流接口.接口名称 == 接口名称 or 数据流接口.序号 == 序号:
                                    日志记录器.debug(f"找到匹配的接口: {数据流接口}")
                                    return 数据流接口  # 如果接口名称或序号匹配，直接返回接口
                        else:
                            日志记录器.debug(f"找到接口: {接口}")
                            raise ValueError(f"数据流接口输入端应为列表，但实际为{接口.__class__.__name__}")
                    else:
                        if 接口.接口名称 == 接口名称 or 接口.序号 == 序号:
                            日志记录器.debug(f"找到匹配的接口: {接口}")
                            return 接口  # 如果接口名称或序号匹配，直接返回接口
                else:
                    日志记录器.debug(f"找到接口: {接口}")
                    return 接口
            新接口 = 节点接口模型(self, 流类型, 方向, 接口名称=接口名称, 数据类型=数据类型, 必须连接=必须连接, 序号=序号)
            self.添加接口到字典(新接口)

            日志记录器.debug(f"添加新接口: {新接口}")
            return 新接口
        except ValueError as e:
            日志记录器.error(f"添加接口时出错: {e}", exc_info=True)

    def 添加接口到字典(self, 接口: 节点接口模型):
        日志记录器.debug(f"添加接口到字典: {接口}")
        if 接口.流类型=="数据流"and 接口.方向=="输入":
            self.接口字典[接口.流类型][接口.方向]+=[接口]
        else:
            self.接口字典[接口.流类型][接口.方向]=接口

        self.设置属性(接口.流类型+接口.方向,  self.接口字典[接口.流类型][接口.方向])
        日志记录器.debug(f"接口字典更新为: {self.接口字典}")
    # def 刷新接口(self):
    #
    def 查找接口(self, 流类型, 方向,) -> 节点接口模型:
        接口 = self.接口字典[流类型][方向]
        日志记录器.debug(f"查找接口: {接口}")
        return 接口

    def 创建连接线模型(self, *args, **kwargs):
        日志记录器.debug("节点模型基类转发：创建连接线模型")
        日志记录器.debug(f"参数: {args}, {kwargs}")
        return self.所属节点模型管理器.创建连接线模型(args, kwargs)
    def 连接节点事件(self, 起点接口, 终点接口):
        print(f"连接节点事件: {self.节点名称} 连接 {起点接口.节点模型.节点名称} 的 {起点接口.接口名称} 接口到 {终点接口.节点模型.节点名称} 的 {终点接口.接口名称} 接口")
